import NextAuth, { DefaultSession, NextAuthConfig } from 'next-auth'
import { PrismaAdapter } from '@auth/prisma-adapter'
import { prisma } from './db'
import Github from 'next-auth/providers/github'
import Gitee from '@/providers/gitee'
import Credentials from 'next-auth/providers/credentials'
import { loginFormSchemaType } from '@/app/auth/login/page'
import bcrypt from 'bcrypt'


declare module 'next-auth' {
  interface Session extends DefaultSession {
    user: {
      id: string,
      credits: number
    } & DefaultSession['user']
  }
}


export const { handlers, signIn, signOut, auth } = NextAuth({
  pages: {
    signIn: '/'
  },
  session: {
    strategy: 'jwt', // 解析策略
  },
  callbacks: {
    jwt: async ({ token, user }) => {
      const db_user = await prisma.user.findFirst({
        where: {
          email: token.email
        }
      })

      // 如果用户存在，则在token上绑定信息
      if (db_user) {
        token.id = db_user.id
        token.credits = db_user.credits
      }

      return token
    },
    session: async ({ session, token }) => {
      session.user.id = token.id as string
      session.user.name = token.name
      session.user.email = token.email as string
      session.user.credits = token.credits as number
      session.user.image = token.picture

      return session
    }
  },
  secret: process.env.NEXTAUTH_SECRET, // 哈希密钥
  adapter: PrismaAdapter(prisma), // prisma 适配器
  providers: [
    Github({
      clientId: process.env.AUTH_GITHUB_ID,
      clientSecret: process.env.AUTH_GITHUB_SECRET
    }),
    Gitee({
      clientId: process.env.AUTH_GITEE_ID,
      clientSecret: process.env.AUTH_GITEE_SERCRET
    }),
    Credentials({
      authorize: async (credentials) => {
        const { email, password } = credentials as loginFormSchemaType

        if (!email || !password) {
          return null
        }
        const user = await prisma.user.findFirst({
          where: {
            email
          }
        })

        if (!user) return null

        if (!(await bcrypt.compare(password, user.password!))) {
          return null
        }
        return user
      }
    })
  ]
})
